package com.weitu.shiro;

import com.weitu.permission.resource.service.ResourceService;
import com.weitu.permission.user.entity.User;
import com.weitu.permission.user.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * 自定义权限认证Realm
 * 登录认证及权限认证
 */
public class MyRealm extends RealmPlate {

    private final UserService userService;//用户信息Service

    private final ResourceService resourceService;

    @Autowired
    public MyRealm(UserService userService, ResourceService resourceService) {
        this.userService = userService;
        this.resourceService = resourceService;
    }

    /**
     * 登录认证函数,登录时调用，验证用户登录信息
     * 异常：
     * AuthenticationException  用户名或密码不匹配
     * LockedAccountException  账号被锁定
     * ExcessiveAttemptsException 登录失败次数过多
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取登录用户名/账号
        String username = (String) token.getPrincipal();
        //根据用户名查询用户信息
        User user = userService.selectByName(username);

        SimpleAuthenticationInfo authenticationInfo;

        if (user != null) {
            if (1 == user.getUseState()) {
                // 密码匹配
                authenticationInfo = new SimpleAuthenticationInfo(
                        username, // 用户名
                        user.getPassword(), // 加密后的密码
                        ByteSource.Util.bytes(username + "" + user.getCredentialsSalt()),// salt=username+salt
                        getName() // realm name
                );
                return authenticationInfo;
            } else {
                throw new LockedAccountException();// 未启用 锁定
            }

        } else {
            throw new UnknownAccountException();// 没找到帐号
        }
    }

    /**
     * 查询用户授权信息
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用;
     * 只有需要验证权限时才会调用, 在配有缓存的情况下，只加载一次.
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取用户名
        String loginName = SecurityUtils.getSubject().getPrincipal().toString();
        if (loginName != null) {
            //查询用户权限(菜单)信息
            Session session = SecurityUtils.getSubject().getSession();
            User loginUser = (User) session.getAttribute("loginUser");

            String deptId = loginUser.getDepartment().getId();
            //封装用户授权信息
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            List<Map> mapList = resourceService.selectAllResourcesByUserId(loginName,deptId);

            for (Map map : mapList) {
                String code=map.get("code").toString();
                info.addStringPermission(code);
            }

            return info;
        }
        return null;
    }


}